package com.tmpt.service.impl;

import com.googlecode.genericdao.search.Search;
import com.googlecode.genericdao.search.SearchResult;
import com.inspiresoftware.lib.dto.geda.adapter.BeanFactory;
import com.inspiresoftware.lib.dto.geda.assembler.DTOAssembler;
import com.tmpt.beans.*;
import com.tmpt.dao.intf.*;
import com.tmpt.service.IOperationlogService;
import com.tmpt.service.ISecurityV2Service;
import com.tmpt.utils.DateTool;
import com.tmpt.dto.*;
import com.tmpt.utils.StringUtils;
import org.apache.log4j.Logger;
import org.json.JSONArray;
import org.json.JSONObject;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.util.*;

@Service
@Transactional(propagation=Propagation.REQUIRED)
public class SecurityV2Service implements ISecurityV2Service {
	@Resource
	IA2CompanyDao a2CompanyDao;
	@Resource
	IA2DeptDao a2DeptDao;
	@Resource
	IA2Menu1Dao a2Menu1Dao;
	@Resource
	IA2Menu1MyDao a2Menu1MyDao;
	@Resource
	IA2Menu2Dao a2Menu2Dao;
	@Resource IA2Menu2MyDao a2Menu2MyDao;
	@Resource
	IA2MenuFunctionDao a2MenuFunctionDao;
	@Resource IA2RoleDao a2RoleDao;
	@Resource IA2UserDao a2UserDao;
	@Resource IA2UserHistoryDao a2UserHistoryDao;
	@Resource
	IA2UserDesktopDao a2UserDesktopDao;
	 
	@Resource
	private IOperationlogService operationlogService;

	private Logger log = Logger.getLogger(this.getClass());
	
	
	@Override
	public Result addA2Menu1(A2Menu1Dto menu1Dto, A1OperationlogDto logDto) {
		Result result = new Result();
		
		A2Menu1 a2Menu1 = new A2Menu1();
		a2Menu1.setText(menu1Dto.getText());
		a2Menu1.setSort(menu1Dto.getSort());
		a2Menu1Dao.create(a2Menu1);
		
		//日志
		if(logDto != null){
			logDto.setLogTypeName("后台：员工管理");
			logDto.setDescription("添加一级菜单："+menu1Dto.getText());
			operationlogService.addOperationlog(logDto);
		}
		return result.success();
	}


	@Override
	public Result addA2Menu2(long a2Menu1Id, A2Menu2Dto menu2Dto, A1OperationlogDto logDto) {
		Result result = new Result();
		
		//Check
		//url不可以重复
		Search search = new Search();
		search.addFilterEqual("url", menu2Dto.getUrl());
		int count = a2Menu2Dao.count(search);
		if(count != 0){
			return result.fault("url已存在");
		}
		
		A2Menu2 a2Menu2 = new A2Menu2();
		a2Menu2.setText(menu2Dto.getText());
		a2Menu2.setSort(menu2Dto.getSort());
		a2Menu2.setUrl(menu2Dto.getUrl());
		a2Menu2.setA2Menu1(a2Menu1Dao.fetch(a2Menu1Id));
		a2Menu2Dao.create(a2Menu2);
		
		/*
		//直接添加一个menu function url
		A2MenuFunctionDto menuFunDto = new A2MenuFunctionDto();
		menuFunDto.setText(menu2Dto.getText());
		menuFunDto.setUrl(menu2Dto.getUrl());
		menuFunDto.setAccessTypeLevel(0);
		securityV2Service.addA2MenuFunction(a2Menu2.getId(), menuFunDto, logDto);
		*/
		
		//日志
		if(logDto != null){
			logDto.setLogTypeName("后台：员工管理");
			logDto.setDescription("添加二级菜单："+menu2Dto.getText());
			operationlogService.addOperationlog(logDto);
		}
		return result.success();
	}


	@Override
	public Result addA2MenuFunction(long a2Menu2Id, A2MenuFunctionDto menuFunDto, A1OperationlogDto logDto) {
		Result result = new Result();
		
		A2MenuFunction a2MenuFunction = new A2MenuFunction();
		DTOAssembler assembler = DTOAssembler.newAssembler(A2MenuFunctionDto.class);
		assembler.assembleEntity(menuFunDto, a2MenuFunction, null, null);
		
		a2MenuFunction.setA2Menu2(a2Menu2Dao.fetch(a2Menu2Id));
		a2MenuFunctionDao.create(a2MenuFunction);
		
		//日志
		if(logDto != null){
			logDto.setLogTypeName("后台：员工管理");
			logDto.setDescription("添加功能资源url："+menuFunDto.getText());
			operationlogService.addOperationlog(logDto);
		}
		return result.success();
	}

	@Override
	public Result addA2Compnay(A2CompanyDto a2CompanyDto,
			A1OperationlogDto logDto) {
		Result result = new Result();
		
		A2Company a2Company = new A2Company();
		a2Company.setName(a2CompanyDto.getName());
		a2CompanyDao.create(a2Company);
		
		//日志
		if(logDto != null){
			logDto.setLogTypeName("后台：员工管理");
			logDto.setDescription("添加公司："+a2CompanyDto.getName());
			operationlogService.addOperationlog(logDto);
		}
		return result.success();
	}
	
	@Override
	public Result<A2CompanyDto> queryA2CompnayList(Search search){
		Result<A2CompanyDto> result = new Result<A2CompanyDto>();
		List<A2CompanyDto> a2CompanyDtoList = new ArrayList<A2CompanyDto>();
		
		List<A2Company> a2CompanyList = a2CompanyDao.search(search);
		DTOAssembler assembler = DTOAssembler.newAssembler(A2CompanyDto.class);
		assembler.assembleDtos(a2CompanyDtoList, a2CompanyList, null, new BeanFactory() {
			@Override
			public Object get(String bean) {
				if ("a2DeptDto".equals(bean)) {
					return new A2DeptDto();
				}
				return null;
			}
		});
		
		result.setResultList(a2CompanyDtoList);
		return result.success();
	}
	
	@Override
	public Result addA2Dept(long a2CompanyId, A2DeptDto a2DeptDto,
		A1OperationlogDto logDto) {
		
		Result result = new Result();
		
		A2Dept a2Dept = new A2Dept();
		a2Dept.setName(a2DeptDto.getName());
		a2Dept.setA2Company(a2CompanyDao.fetch(a2CompanyId));
		a2DeptDao.create(a2Dept);
		
		//日志
		if(logDto != null){
			logDto.setLogTypeName("后台：员工管理");
			logDto.setDescription("添加部门："+a2DeptDto.getName());
			operationlogService.addOperationlog(logDto);
		}
		return result.success();
	}
	
	@Override
	public Result addA2User(long a2DeptId, A2UserDto a2UserDto,
			A1OperationlogDto logDto) {
		Result result = new Result();
		A2Dept a2Dept = a2DeptDao.fetch(a2DeptId);
		
		A2User a2User = new A2User();
		DTOAssembler assembler = DTOAssembler.newAssembler(A2UserDto.class);
		assembler.assembleEntity(a2UserDto, a2User, null, null);
		a2User.setA2Dept(a2Dept);
		//a2User.setA2Company(a2Dept.getA2Company());
		a2UserDao.create(a2User);
		
		//日志
		if(logDto != null){
			logDto.setLogTypeName("后台：员工管理");
			logDto.setDescription("添加员工："+a2UserDto.getName());
			operationlogService.addOperationlog(logDto);
		}
		return result.success();
	}
	
	@Override
	public Result addA2Role(A2RoleDto a2RoleDto, A1OperationlogDto logDto) {
		Result result = new Result();
		
		A2Role a2Role = new A2Role();
		DTOAssembler assembler = DTOAssembler.newAssembler(A2RoleDto.class);
		assembler.assembleEntity(a2RoleDto, a2Role, null, null);
		a2RoleDao.create(a2Role);
		
		//日志
		if(logDto != null){
			logDto.setLogTypeName("后台：员工管理");
			logDto.setDescription("添加角色："+a2RoleDto.getRoleName());
			operationlogService.addOperationlog(logDto);
		}
		return result.success();
	}
	
	@Override
	public Result<A2RoleDto> queryA2RoleList() {
		Result<A2RoleDto> result = new Result<A2RoleDto>();
		List<A2RoleDto> roleDtoList = new ArrayList<A2RoleDto>();
		
		Search search = new Search();
		search.addFilterEqual("deleteFlag", "0");
		List<A2Role> roleList = a2RoleDao.search(search);
		
		//Assembler
		DTOAssembler assembler = DTOAssembler.newAssembler(A2RoleDto.class);
		assembler.assembleDtos(roleDtoList, roleList, null, null);
		
		result.setResultList(roleDtoList);
		return result.success();
	}

	@Override
	public Result<A2RoleDto> queryA2RoleListByUser(long userId) {
		Result<A2RoleDto> result = new Result<A2RoleDto>();
		List<A2RoleDto> roleDtoList = new ArrayList<A2RoleDto>();
		
		A2User user = a2UserDao.fetch(userId);
		a2UserDao.refresh(user);//dddddddddd
		List<A2Role> roleList = user.getA2RoleList();
		
		//Assembler
		DTOAssembler assembler = DTOAssembler.newAssembler(A2RoleDto.class);
		assembler.assembleDtos(roleDtoList, roleList, null, null);
		
		result.setResultList(roleDtoList);
		return result.success();
	}
	
	/*
	@Override
	public Result bindRole_Menu(long roleId, Map<Long,Map<Long,String>> menu1IdMap, A1OperationlogDto logDto) {
		Result result = new Result();
		//取角色
		A2Role a2Role = a2RoleDao.fetch(roleId);
		
		//取Menu 同时灌入  A2Menu1My
		Iterator<Long> it = menu1IdMap.keySet().iterator();
		while(it.hasNext()){
			Long menu1Id = it.next();
			A2Menu1 menu1 = a2Menu1Dao.fetch(menu1Id);
			A2Menu1My menu1My = new A2Menu1My();
			menu1My.setA2Menu1(menu1);
			menu1My.setA2Role(a2Role);
			a2Menu1MyDao.create(menu1My);
			
			//2级菜单
			Map<Long,String> menu2Map = menu1IdMap.get(menu1Id);
			Iterator<Long> it2 = menu2Map.keySet().iterator();
			while(it2.hasNext()){
				long menu2Id = it2.next();
				String accessType = menu2Map.get(menu2Id);
				A2Menu2 menu2 = a2Menu2Dao.fetch(menu2Id);
				A2Menu2My menu2My = new A2Menu2My();
				menu2My.setAccessType(accessType);//设访问类型
				menu2My.setA2Menu2(menu2);
				menu2My.setA2Menu1My(menu1My);
				a2Menu2MyDao.create(menu2My);
			}
			
		}
		
		//日志
		if(logDto != null){
			logDto.setLogTypeName("后台：员工管理");
			logDto.setDescription("绑定角色 和 菜单：roleId:"+roleId+" menu2IdList:"+menu1IdMap.toString());
			operationlogService.addOperationlog(logDto);
		}
		return result.success();
	}
	*/

	@Override
	public Result bindRole_Menu(String roleName, Map<Long,Map<Long,Map<String,Object>>> menu1IdMap, A1OperationlogDto logDto) {
		Result result = new Result();

		//.out.println("-----------roleName"+roleName);
		//取角色
		Search search = new Search();
		search.addFilterEqual("roleName", roleName);
		Object a2RoleObj = a2RoleDao.searchUnique(search);
		A2Role a2Role = null;
		if(a2RoleObj == null){
			//add a role
			a2Role = new A2Role();
			a2Role.setRoleName(roleName);
			a2RoleDao.create(a2Role);
		}else{
			a2Role = (A2Role)a2RoleObj;
		}
		//.out.println("-----------a2Role.getA2Menu1MyList().size()" + a2Role.getA2Menu1MyList().size());
		//角色下已存在菜单，先删除这些菜单
		if(a2Role.getA2Menu1MyList().size()>0){
			for(A2Menu1My menu1My : a2Role.getA2Menu1MyList()){
				a2Menu1MyDao.deleteEntity(menu1My);
			}
		}
		
		//取Menu 同时灌入  A2Menu1My
		Iterator<Long> it = menu1IdMap.keySet().iterator();
		while(it.hasNext()){
			Long menu1Id = it.next();
			A2Menu1 menu1 = a2Menu1Dao.fetch(menu1Id);
			A2Menu1My menu1My = new A2Menu1My();
			menu1My.setA2Menu1(menu1);
			menu1My.setA2Role(a2Role);
			a2Menu1MyDao.create(menu1My);
			
			//2级菜单
			Map<Long,Map<String,Object>> menu2Map = menu1IdMap.get(menu1Id);
			Iterator<Long> it2 = menu2Map.keySet().iterator();
			while(it2.hasNext()){
				long menu2Id = it2.next();
				Map<String,Object> attrMap = menu2Map.get(menu2Id);
				int accessTypeLevel = (Integer)attrMap.get("accessTypeLevel");
				int dataLimitType = 0 ;
				if(attrMap.get("dataLimitType") != null){
					dataLimitType = (Integer)attrMap.get("dataLimitType");
				}
				A2Menu2 menu2 = a2Menu2Dao.fetch(menu2Id);
				A2Menu2My menu2My = new A2Menu2My();
				menu2My.setAccessTypeLevel(accessTypeLevel);//设访问类型
				menu2My.setDataLimitType(dataLimitType);
				menu2My.setA2Menu2(menu2);
				menu2My.setA2Menu1My(menu1My);
				a2Menu2MyDao.create(menu2My);
			}
			
		}
		
		//日志
		if(logDto != null){
			logDto.setLogTypeName("后台：员工管理");
			logDto.setDescription("绑定角色 和 菜单：roleName:"+roleName+" menu2IdList:"+menu1IdMap.toString());
			operationlogService.addOperationlog(logDto);
		}
		return result.success();
	}
	

	@Override
	public Result bindUser_Role(long userId, List<Long> roleIdList, A1OperationlogDto logDto) {
		Result result = new Result();
		//.out.println("====="+userId);
		//Get User
		A2User user = a2UserDao.fetch(userId);

		//清除原来关系
		user.getA2RoleList().clear();
		a2UserDao.update(user);
		
		//取角色
		for(Long roleId : roleIdList){
			A2Role role = a2RoleDao.fetch(roleId);
			user.getA2RoleList().add(role);
		}
		a2UserDao.update(user);
		
		//日志
		if(logDto != null){
			logDto.setLogTypeName("后台：员工管理");
			logDto.setDescription("给用户分配角色：userId:"+userId+" roleIdList:"+roleIdList.toString());
			operationlogService.addOperationlog(logDto);
		}
		return result.success();
	}
	
	@Override
	public Result<A2Menu1Dto> queryMenu1List() {

		Result<A2Menu1Dto> result = new Result<A2Menu1Dto>();
		List<A2Menu1Dto> menu1DtoList = new ArrayList<A2Menu1Dto>();

		Search search = new Search();
		search.addFilterEqual("deleteFlag", "0");
		List<A2Menu1> menu1List = a2Menu1Dao.search(search);
		//排序
		Collections.sort(menu1List, new Comparator<A2Menu1>() {
			@Override
			public int compare(A2Menu1 o1, A2Menu1 o2) {
				return o1.getSort() - o2.getSort();
			}
		});

		//Assembler
		DTOAssembler assembler = DTOAssembler.newAssembler(A2Menu1Dto.class);
		assembler.assembleDtos(menu1DtoList, menu1List, null, null);


		result.setResultList(menu1DtoList);
		return result.success();
	}
	
	
	//[{"text":"系统基本信息管理",'state':'closed',"children":[{"text":"修改密码","attributes":{"url":"user/changePwd.jsp"}},{"text":"修改个人资料","attributes":{"url":"user/changeMyInfo.jsp"}},{"text":"部门管理","attributes":{"url":"user/deptMag.jsp"}},{"text":"后台用户管理","attributes":{"url":"user/userList.jsp"}},{"text":"角色权限配置","attributes":{"url":"user/cfgRoleAuth.jsp"}},{"text":"操作日志查询","attributes":{"url":"log/logList.jsp"}},{"text":"模板页面管理","attributes":{"url":"template/tableList.jsp"}}]},{"text":"客户管理",'state':'closed',"children":[{"text":"个人用户列表","attributes":{"url":"user/customerList.jsp"}}]},{"text":"商户管理",'state':'closed',"children":[{"text":"代理商管理","attributes":{"url":"merchant/merchantAgentList.jsp"}},{"text":"费率管理","attributes":{"url":"merchant/merchantRateList.jsp"}},{"text":"商户增加","attributes":{"url":"merchant/merchantInfoAdd.jsp"}},{"text":"商户列表","attributes":{"url":"merchant/merchantInfoList.jsp"}}]},{"text":"商户平台管理",'state':'closed',"children":[]},{"text":"合作银行管理",'state':'closed',"children":[{"text":"合作银行增加","attributes":{"url":"bankpatcoop/bankPatCoopAdd.jsp"}},{"text":"合作银行列表","attributes":{"url":"bankpatcoop/bankPatCoopList.jsp"}}]},{"text":"退货/取消管理",'state':'closed',"children":[{"text":"退货/取消管理","attributes":{"url":"orderMerReturnMoneyApply/orderMerReturnMoneyApplyList.jsp"}}]},{"text":"网关订单管理",'state':'closed',"children":[{"text":"商品订单列表","attributes":{"url":"order/orderProductList.jsp"}},{"text":"支付订单列表","attributes":{"url":"order/orderPayList.jsp"}},{"text":"银行订单列表","attributes":{"url":"order/orderBankList.jsp"}}]},{"text":"财务结算",'state':'closed',"children":[{"text":"商户结算列表","attributes":{"url":"finacial/finacialOrderProductList.jsp"}},{"text":"银行对账列表","attributes":{"url":"finacial/finacialOrderPayList.jsp"}},{"text":"账户余额统计","attributes":{"url":"template/templateList.jsp?keyRandom=20150423144439356"}},{"text":"汇总表","attributes":{"url":"template/templateList.jsp?keyRandom=20150423145252903"}},{"text":"收单商户运营明细表","attributes":{"url":"template/templateList.jsp?keyRandom=20150423145707996"}},{"text":"商户结算单","attributes":{"url":"template/templateList.jsp?keyRandom=20150423145934153"}},{"text":"银行对账单","attributes":{"url":"template/templateList.jsp?keyRandom=20150423150511418"}}]},{"text":"划款处理",'state':'closed',"children":[]},{"text":"自营产品订单管理",'state':'closed',"children":[{"text":"自营产品订单列表","attributes":{"url":"order/orderProductMyList.jsp"}},{"text":"手机充值订单列表","attributes":{"url":"mobile/mobileInfoList.jsp"}},{"text":"油卡充值订单列表","attributes":{"url":"oilCard/oilCardInfoList.jsp"}}]},{"text":"自营产品通道管理",'state':'closed',"children":[{"text":"手机充值通道管理","attributes":{"url":"channel/mobileChannelChange.jsp"}}]},{"text":"test订单管理",'state':'closed',"children":[]},{"text":"弘康管理",'state':'closed',"children":[]},{"text":"风控管理",'state':'closed',"children":[{"text":"风控规则管理","attributes":{"url":"systemMag/systemMag_queryRiskRule.action"}},{"text":"风控黑名单","attributes":{"url":"systemMag/riskBlackList.jsp"}},{"text":"风控记录列表","attributes":{"url":"systemMag/riskPayOrderList.jsp"}}]},{"text":"退出系统",'state':'closed',"children":[{"text":"退出","attributes":{"url":"logout"}}]}]
	@Override
	public Result queryMenusByUser(long userId) {

		Result result = new Result();
		List<A2Menu1> menu1List = new ArrayList<A2Menu1>();
		JSONArray jsonArr = new JSONArray();
		A2User user = a2UserDao.fetch(userId);
		//取用户所有角色
		int i = 0;
		List<A2Role> roleList = user.getA2RoleList();
		for(A2Role role : roleList){
			//角色 所拥有的 一级菜单
			List<A2Menu1My> menu1MyList = role.getA2Menu1MyList();
			for(A2Menu1My menu1My : menu1MyList){
				//一级菜单数据
				if(menu1My.getA2Menu1().getDeleteFlag()==1)continue;
				long m1_id = menu1My.getA2Menu1().getId();
				int m1_sort = menu1My.getA2Menu1().getSort();
				String m1_text = menu1My.getA2Menu1().getText();
				String m1_icon = menu1My.getA2Menu1().getIconClass();
				//
				A2Menu1 menu1 = new A2Menu1();
				menu1.setId(m1_id);
				menu1.setSort(m1_sort);
				menu1.setText(m1_text);
				menu1.setIconClass(m1_icon);
				//是否包含1级菜单了
				Result<A2Menu1> resultContain = contain(menu1List, menu1);
				if(resultContain.isSuccess()){
					menu1 = resultContain.getResultObj();
				}else{
					menu1List.add(menu1);
				}
				//角色 所拥有的 二级菜单
				for(A2Menu2My menu2My:menu1My.getA2Menu2MyList()){
					if(menu2My.getA2Menu2().getDeleteFlag()==1)continue;
					long m2_id = menu2My.getA2Menu2().getId();
					int m2_sort = menu2My.getA2Menu2().getSort();
					String m2_text = menu2My.getA2Menu2().getText();
					String m2_url = menu2My.getA2Menu2().getUrl();
					String m2_icon = menu2My.getA2Menu2().getIconClass();
					A2Menu2 menu2 = new A2Menu2();
					menu2.setId(m2_id);
					menu2.setText(m2_text);
					menu2.setSort(m2_sort);
					menu2.setUrl(m2_url);
					menu2.setIconClass(m2_icon);

					List<A2Menu2> menu2List = menu1.getA2Menu2List();
					if(!contain(menu2List, menu2)){
						menu2List.add(menu2);
					}
					
				}
			}
		}

		//排序
		Collections.sort(menu1List, new Comparator<A2Menu1>() {
			@Override
			public int compare(A2Menu1 o1, A2Menu1 o2) {
				return o1.getSort() - o2.getSort();
			}
		});
		for(A2Menu1 menu1: menu1List){
			String menu1Id = String.valueOf(menu1.getId());
			String menu1Text = menu1.getText();
			String menu1iconClass = menu1.getIconClass();
			JSONObject joMenu1 = new JSONObject();
			joMenu1.put("id", menu1Id);
			joMenu1.put("text", menu1Text);
			joMenu1.put("iconClass", menu1iconClass);
			//默认展开第一项
			if(i++ != 0){
				joMenu1.put("state", "closed");
			}
			
			//menu2
			List<A2Menu2> menu2List = menu1.getA2Menu2List();
			
			//排序
			Collections.sort(menu2List, new Comparator<A2Menu2>() {
				@Override
				public int compare(A2Menu2 o1, A2Menu2 o2) {
					return o1.getSort()-o2.getSort();
				}
			});
			
			//角色 所拥有的 二级菜单
			JSONArray jaChildren = new JSONArray();
			for(A2Menu2 menu2:menu2List){
				String menu2Id = String.valueOf(menu2.getId());
				String menu2Text = menu2.getText();
				String menu2Url = menu2.getUrl();
				String menu2iconClass = menu2.getIconClass();
				JSONObject joMenu2 = new JSONObject();
				joMenu2.put("id", menu1Id+"_"+menu2Id);
				/*joMenu2.put("menu2Id", menu2Id);*/
				joMenu2.put("text", menu2Text);
				joMenu2.put("iconClass", menu2iconClass);
				joMenu2.put("href", "/zpmng/"+menu2Url);
				JSONObject joAttr = new JSONObject();
				joAttr.put("url", menu2Url);
				joAttr.put("menu2Id", menu2Id);
				joMenu2.put("attributes", joAttr);
				jaChildren.put(joMenu2); 
			}
			joMenu1.put("children", jaChildren);
			jsonArr.put(joMenu1);
		}
		
		String menuJson = jsonArr.toString();
		//.out.println("menuJson:" + menuJson);
		result.getResultMap().put("menuJson", menuJson);
		return result.success();
	}
	
	public Result<A2Menu1> contain(List<A2Menu1> menu1List, A2Menu1 menu1){
		Result<A2Menu1> result = new Result<A2Menu1>();
		for(A2Menu1 menu1Tmp : menu1List){
			if(menu1Tmp.getText().equals(menu1.getText())){
				result.setResultObj(menu1Tmp);
				return result.success();
			}
		}
		return result.fault();
	}

	public boolean contain(List<A2Menu2> menu2List, A2Menu2 menu2){
		for(A2Menu2 menu2Tmp : menu2List){
			if(menu2Tmp.getText().equals(menu2.getText())){
				return true;
			}
		}
		return false;
	}
	

	@Override
	public Result queryMenus4Conf() {
		Result result = new Result();
		JSONArray jsonArr = new JSONArray();
		
		Search searchMenu1 = new Search();
		searchMenu1.addFilterEqual("deleteFlag", 0);
		List<A2Menu1> menu1List = a2Menu1Dao.search(searchMenu1);
		for(A2Menu1 menu1 : menu1List){
			JSONObject joMenu1 = new JSONObject();
			Long menu1Id = menu1.getId();
			String menu1Text = menu1.getText();
			joMenu1.put("text", menu1Id+"，"+menu1Text);
			//joMenu1.put("state", "closed");
			
			//角色 所拥有的 二级菜单
			JSONArray jaChildren = new JSONArray();
			for(A2Menu2 menu2 : menu1.getA2Menu2List()){
				Long menu2Id = menu2.getId();
				String menu2Text = menu2.getText();
				String menu2Url = menu2.getUrl();
				JSONObject joMenu2 = new JSONObject();
				joMenu2.put("text", menu2Id+"，"+menu2Text+"，"+menu2Url);
				joMenu2.put("state", "closed");
				//二级菜单的功能列表
				JSONArray jaFuns = new JSONArray();
				for(A2MenuFunction menuFun: menu2.getA2MenuFunctionList()){
					String funText = menuFun.getText();
					String funUrl = menuFun.getUrl();
					int funAccessTypeLevel = menuFun.getAccessTypeLevel();
					JSONObject joMenuFun = new JSONObject();
					joMenuFun.put("text", funText+"，"+funAccessTypeLevel+"；"+funUrl);
					jaFuns.put(joMenuFun);
				}
				joMenu2.put("children", jaFuns);
				
				jaChildren.put(joMenu2);
			}
			joMenu1.put("children", jaChildren);
			jsonArr.put(joMenu1);
		}
		
		String menuJson = jsonArr.toString();
		//.out.println("menuJson:" + menuJson);
		result.getResultMap().put("menuJson", menuJson);
		return result.success();
	}
	

	@Deprecated
	@Override
	public Result queryMenus4RoleConf() {
		Result result = new Result();
		JSONArray jsonArr = new JSONArray();
		
		JSONObject joAttr = null;
		Search searchMenu1 = new Search();
		searchMenu1.addFilterEqual("deleteFlag", 0);
		List<A2Menu1> menu1List = a2Menu1Dao.search(searchMenu1);
		for(A2Menu1 menu1 : menu1List){
			JSONObject joMenu1 = new JSONObject();
			Long menu1Id = menu1.getId();
			String menu1Text = menu1.getText();
			joMenu1.put("text", menu1Id+"，"+menu1Text);
			joMenu1.put("id", menu1Id);
			//joMenu1.put("state", "closed");
			//一级菜单上的属性
			joAttr = new JSONObject();
			joAttr.put("level", 1);
			joAttr.put("id", menu1Id);
			joMenu1.put("attributes", joAttr);
			
			//角色 所拥有的 二级菜单
			JSONArray jaChildren = new JSONArray();
			for(A2Menu2 menu2 : menu1.getA2Menu2List()){
				Long menu2Id = menu2.getId();
				String menu2Text = menu2.getText();
				String menu2Url = menu2.getUrl();
				int hasDataLimit = menu2.getHasDataLimit();
				JSONObject joMenu2 = new JSONObject();
				joMenu2.put("text", menu2Id+"，"+menu2Text);
				joMenu2.put("id", menu1Id+"_"+menu2Id);
				//joMenu1.put("state", "closed");
				//二级菜单上的属性
				joAttr = new JSONObject();
				joAttr.put("id", menu2Id);
				joAttr.put("menu1Id", menu1Id);
				joAttr.put("menu2Id", menu2Id);
				joAttr.put("level", 2);
				joAttr.put("checkState", "true");
				joAttr.put("url", menu2Url);
				joAttr.put("hasDataLimit", hasDataLimit);
				joMenu2.put("attributes", joAttr);

				jaChildren.put(joMenu2);
			}
			joMenu1.put("children", jaChildren);
			jsonArr.put(joMenu1);
		}
		
		String menuJson = jsonArr.toString();
		//.out.println("menuJson:" + menuJson);
		result.getResultMap().put("menuJson", menuJson);
		return result.success();
	}
	
	

	@Deprecated
	@Override
	public Result queryMenus4RoleConfByRoleId(long roleId) {
		Result result = new Result();
		JSONArray jsonArr = new JSONArray();
		//取某角色拥有的 菜单
		A2Role a2Role = a2RoleDao.fetch(roleId);
		List<A2Menu1My> menu1MyList = a2Role.getA2Menu1MyList();
		for(A2Menu1My menu1My: menu1MyList){
			A2Menu1 a2Menu1 = menu1My.getA2Menu1();
			long menu1Id = a2Menu1.getId();
			int a2Menu1DeleteFlag = a2Menu1.getDeleteFlag();
			if(a2Menu1DeleteFlag==1){continue;}
			List<A2Menu2My> menu2MyList =  menu1My.getA2Menu2MyList();
			for(A2Menu2My menu2My : menu2MyList){
				A2Menu2 a2Menu2 = menu2My.getA2Menu2();
				if(a2Menu2.getDeleteFlag()==1){continue;}
				long menu2Id = a2Menu2.getId();
				int accessTypeLevel = menu2My.getAccessTypeLevel();
				int dataLimitType = menu2My.getDataLimitType();
				JSONObject jo = new JSONObject();
				jo.put("menu1Id", menu1Id);
				jo.put("menu2Id", menu2Id);
				jo.put("menu2Id4Tree", menu1Id+"_"+menu2Id);
				jo.put("accessTypeLevel", accessTypeLevel);
				jo.put("dataLimitType", dataLimitType);
				//jo.put("accessTypeLevel", "radio_"+menu1Id+"_"+menu2Id+"_"+accessTypeLevel);
				jsonArr.put(jo);
			}
		}
		
		String menu4RoleConfByRoleIdJson = jsonArr.toString();
		//.out.println("menu4RoleConfByRoleIdJson:" + menu4RoleConfByRoleIdJson);
		result.getResultMap().put("menu4RoleConfByRoleIdJson", menu4RoleConfByRoleIdJson);
		return result.success();
	}
	
	/**
	 * 登录时调用
	 * @param loginname
	 * @return
	 */
	@Override
	public A2UserDto getUserByLoginname(String loginname){
		A2UserDto userDto = new A2UserDto();
		
		Search search = new Search();
		search.addFilterEqual("loginName", loginname);
		search.addFilterEqual("deleteFlag", 0);
		A2User user = (A2User)a2UserDao.searchUnique(search);
		//a2UserDao.refresh(user);
		////.out.println("========:"+user.getName());
		if(user == null){
			return null;
		}

		long companyId = 0;
		if(user.getA2Post()!=null){
			if(user.getA2Post().getA2Company()!=null){
				companyId = user.getA2Post().getA2Company().getId();
			}
		}

		DTOAssembler ass = DTOAssembler.newAssembler(A2UserDto.class);
		ass.assembleDto(userDto, user, null, null);
		userDto.setCompanyId(companyId);


		/*
		//取用户权限列表（menu2Url_0/1/2）0/1/2表示读、写、机密
		for(A2Role role : user.getA2RoleList()){
			a2RoleDao.refresh(role);
			for(A2Menu1My menu1My : role.getA2Menu1MyList()){
				//a2Menu1MyDao.refresh(menu1My);
				for(A2Menu2My menu2My : menu1My.getA2Menu2MyList()){
					A2Menu2 menu2 = menu2My.getA2Menu2();
					//a2Menu2Dao.refresh(menu2);
					String menu2Text = menu2.getText();
					////.out.println("menu2Text:"+menu2Text);
					int menu2AccessTypeLevel = menu2My.getAccessTypeLevel();
					String menu2Auth = "";
					if(menu2AccessTypeLevel == 2){
						menu2Auth = menu2Text+"_0";
						userDto.getMenu2AuthList().add(menu2Auth);
						menu2Auth = menu2Text+"_1";
						userDto.getMenu2AuthList().add(menu2Auth);
						menu2Auth = menu2Text+"_2";
						userDto.getMenu2AuthList().add(menu2Auth);
					}
					if(menu2AccessTypeLevel == 1){
						menu2Auth = menu2Text+"_0";
						userDto.getMenu2AuthList().add(menu2Auth);
						menu2Auth = menu2Text+"_1";
						userDto.getMenu2AuthList().add(menu2Auth);
					}
					if(menu2AccessTypeLevel == 0){
						menu2Auth = menu2Text+"_0";
						userDto.getMenu2AuthList().add(menu2Auth);
					}
				}
			}
		}*/
		////.out.println("userDto.getMenu2AuthList():"+userDto.getMenu2AuthList());

		return userDto;
	}

	/**
	 * App登录时调用
	 * @param appLoginname
	 * @return
	 */
	@Override
	public A2UserDto getUserByAppLoginname(String appLoginname){
		A2UserDto userDto = new A2UserDto();

		Search search = new Search();
		search.addFilterEqual("appLoginname", appLoginname);
		search.addFilterEqual("deleteFlag", 0);
		A2User user = (A2User)a2UserDao.searchUnique(search);
		//a2UserDao.refresh(user);
		////.out.println("========:"+user.getName());
		if(user == null){
			return null;
		}

		long companyId = 0;
		String a2postName = "";
		if(user.getA2Post()!=null){
			a2postName = user.getA2Post().getName();
			if(user.getA2Post().getA2Company()!=null){
				companyId = user.getA2Post().getA2Company().getId();
			}
		}

		DTOAssembler ass = DTOAssembler.newAssembler(A2UserDto.class);
		ass.assembleDto(userDto, user, null, null);
		userDto.setCompanyId(companyId);
		userDto.setA2postName(a2postName);

		return userDto;
	}

	/**
	 * 个推中clientID更新
	 * @param userId
	 * @param clientID
	 * @return
	 */
	@Override
	public Result updateClientIDByUser(String userId, String clientID){
		Result result = new Result();

		if(StringUtils.isNull(clientID)){
			return result.success();
		}

		Search search = new Search();
		search.addFilterEqual("id", userId);
		A2User user = (A2User)a2UserDao.searchUnique(search);
		user.setClientID(clientID);
		a2UserDao.update(user);

		return  result.success();
	}

	/**
	 * 查看个人资料
	 * @param userId
	 * @return
	 */
	@Override
	public A2UserDto queryUserById(String userId){
		A2UserDto userDto = new A2UserDto();

		Search search = new Search();
		search.addFilterEqual("id", userId);
		A2User user = (A2User)a2UserDao.searchUnique(search);
		if(user == null){
			return null;
		}

		long companyId = 0;
		String a2postName = "";
		if(user.getA2Post()!=null){
			a2postName = user.getA2Post().getName();
			if(user.getA2Post().getA2Company()!=null){
				companyId = user.getA2Post().getA2Company().getId();
			}
		}

		DTOAssembler ass = DTOAssembler.newAssembler(A2UserDto.class);
		ass.assembleDto(userDto, user, null, null);
		userDto.setCompanyId(companyId);
		userDto.setA2postName(a2postName);

		return userDto;
	}


	@Override
	public Set<String> getMenu2AuthListByUrl(String url){
		Set<String> menu2AuthList = new HashSet<String>();
		Search search = new Search();
		search.addFilterEqual("url", url);
		
		List<A2MenuFunction> menuFunctionList = a2MenuFunctionDao.search(search);
		if(menuFunctionList == null || menuFunctionList.size()==0){
			//可能是menu2的访问url
			List<A2Menu2> menu2List = a2Menu2Dao.search(search);
			if(menu2List == null){
				return menu2AuthList;
			}
			for(A2Menu2 menu2:menu2List){
				String menu2Text = menu2.getText();
				int menu2AccessTypeLevel = 0;
				String menu2Auth = menu2Text+"_"+menu2AccessTypeLevel;
				menu2AuthList.add(menu2Auth);
			}
		}else{
			for(A2MenuFunction menuFunction : menuFunctionList){
				String menu2Text = menuFunction.getA2Menu2().getText();
				int menu2AccessTypeLevel = menuFunction.getAccessTypeLevel();
				String menu2Auth = menu2Text+"_"+menu2AccessTypeLevel;
				menu2AuthList.add(menu2Auth);
			}
		}
		////.out.println("getMenu2AuthListByUrl:"+menu2AuthList);
		return menu2AuthList;
	}

	@Override
	public void recordLastLoginInfo(A2UserDto userDto){
		A2User user = a2UserDao.fetch(userDto.getId());
		user.setLoginTimes(user.getLoginTimes()+1);
		user.setLoginTimeLast(DateTool.getCurTimestamp());
		a2UserDao.update(user);
	}
	
	@Override
	public Result<A2UserDto> queryUserList(Map<String,Object> mapParam){
		Result result = new Result();
		try{
			int page = Integer.parseInt(mapParam.get("page").toString());
			int rows = Integer.parseInt(mapParam.get("rows").toString());
			String sortOrder = mapParam.get("sortOrder").toString();
			String sortColumn = mapParam.get("sortColumn").toString();
			
			Map<String,Object> resultMap = new HashMap<String, Object>();
			StringBuilder sb = new StringBuilder();
			
			//查询条件
			Search search = new Search();
			search.setPage(page-1);
			search.setMaxResults(rows);
			if("desc".equals(sortOrder) && sortColumn!=null){
				search.addSort(sortColumn, true);
			}else if("asc".equals(sortOrder) && sortColumn!=null){
				search.addSort(sortColumn, false);
			}else{
				search.addSort("id", false);
			}
			//字段名在postgresql数据库下需全部改为小写
			search.addFilterEqual("deleteFlag",  mapParam.get("deleteflag"));
			search.addFilterEqual("name",  mapParam.get("name"));
			search.addFilterEqual("loginName",  mapParam.get("loginname"));
			search.addFilterEqual("email",  mapParam.get("email"));
			if(mapParam.get("createdate_Start")!=null){
				search.addFilterGreaterOrEqual("createDate", DateTool.string2Date(mapParam.get("createdate_Start").toString(), "yyyy-MM-dd HH:mm:ss"));
			}
			if(mapParam.get("createdate_End")!=null){
				search.addFilterLessOrEqual("createDate", DateTool.string2DateEnd(mapParam.get("createdate_End").toString()+".999", "yyyy-MM-dd"));
			}
			//公司 部门 search
			Object a2Dept_id = mapParam.get("a2dept_id");
			if(a2Dept_id != null){
				try {
					//是部门id
					Long.parseLong(a2Dept_id.toString());
					search.addFilterEqual("a2Dept.id",  mapParam.get("a2dept_id"));
				} catch (Exception e) {
					//c1:是公司id
					String compId = a2Dept_id.toString().substring(1);
					search.addFilterEqual("a2Dept.a2Company.id",  compId);
				}
			}

			//查询
			SearchResult<A2User> searchResult =  a2UserDao.searchAndCount(search);
			List<A2User> userList = searchResult.getResult();
			int totalCount = searchResult.getTotalCount();
			
			//查询结果
			List<Map<String,Object>> list = new ArrayList<Map<String,Object>>();
			for(A2User user:userList){
				Map<String,Object> columnMap = new HashMap<String, Object>();
				columnMap.put("id", user.getId());
				columnMap.put("name", user.getName());
				columnMap.put("sex", user.getSex()==0?"女":"男");
				columnMap.put("loginname", user.getLoginName());
				columnMap.put("email", user.getEmail());
				columnMap.put("idcardno", user.getIdCardno());
				columnMap.put("password", user.getPassword());
				columnMap.put("createdate", DateTool.date2String(user.getCreateDate(),"yyyy-MM-dd HH:mm:ss"));
				columnMap.put("createman", user.getCreateMan());
				columnMap.put("modifydate", DateTool.date2String(user.getModifyDate(),"yyyy-MM-dd HH:mm:ss"));
				columnMap.put("modifyman", user.getModifyMan());
				columnMap.put("a2company_id", user.getA2Dept().getA2Company().getName());
				columnMap.put("a2dept_id", user.getA2Dept().getName());
				columnMap.put("deleteflag", user.getDeleteFlag()==0?"正常":"已删除");
				columnMap.put("logintimeLast", DateTool.date2String(user.getLoginTimeLast(), "yyyy-MM-dd HH:mm:ss"));
				columnMap.put("logintimes", user.getLoginTimes());
				columnMap.put("phone", user.getPhone());
				columnMap.put("telephone", user.getTelephone());
				
				sb.setLength(0);
				for(A2Role role:user.getA2RoleList()){
					sb.append(role.getRoleName()).append("、");
				}	
				if(sb.length()>1){
					sb.delete(sb.length()-1, sb.length());
				}
				String roleNames = sb.toString();

				columnMap.put("rolenames", roleNames);
				
				list.add(columnMap);
			}

			resultMap.put("total", totalCount);
			resultMap.put("rows", list);
			
			result.setResultMap(resultMap);
			return result.success();
		}catch (Exception e) {
			e.printStackTrace();
			return result.fault();
		}
	}

	@Override
	public Result<A2UserDto> queryUserHistoryList(Map<String,Object> mapParam){
		String _historyId = (String)mapParam.get("_historyId");
		
		Result result = new Result();
		Map<String,Object> resultMap = new HashMap<String, Object>();
		StringBuilder sb = new StringBuilder();
		
		Search search = new Search();
		search.addFilterEqual("id", _historyId);
		search.addSort("createDate", true);
		SearchResult<A2UserHistory> searchResult = a2UserHistoryDao.searchAndCount(search);
		List<A2UserHistory> userHistoryList = searchResult.getResult();
		int count = searchResult.getTotalCount();
		List<Map<String,Object>> list = new ArrayList<Map<String,Object>>();
		for(A2UserHistory userHistory:userHistoryList){
			Map<String,Object> columnMap = new HashMap<String, Object>();
			columnMap.put("id", userHistory.getId());
			columnMap.put("name", userHistory.getName());
			columnMap.put("sex", userHistory.getSex()==0?"女":"男");
			columnMap.put("loginName", userHistory.getLoginName());
			columnMap.put("email", userHistory.getEmail());
			columnMap.put("idCardno", userHistory.getIdCardno());
			columnMap.put("password", userHistory.getPassword());
			columnMap.put("createDate", DateTool.date2String(userHistory.getCreateDate(),"yyyy-MM-dd HH:mm:ss"));
			columnMap.put("createMan", userHistory.getCreateMan());
			columnMap.put("modifyDate", DateTool.date2String(userHistory.getModifyDate(),"yyyy-MM-dd HH:mm:ss"));
			columnMap.put("modifyMan", userHistory.getModifyMan());
			columnMap.put("a2Company_id", userHistory.getA2Dept().getA2Company().getName());
			columnMap.put("a2Dept_id", userHistory.getA2Dept().getName());
			columnMap.put("roleNames", "未备份");
			//.out.println(userHistory.getEmail());
			list.add(columnMap);
		}


		resultMap.put("total", count);
		resultMap.put("rows", list);
		
		result.setResultMap(resultMap);
		return result.success();
	}
	

	@Override
	public Result queryDesktopByUser(long userId){
		Result<A2UserDesktopDto> result = new Result<A2UserDesktopDto>(); 
		List<A2UserDesktopDto> desktopDtoList = new ArrayList<A2UserDesktopDto>();
		
		Search search = new Search();
		search.addFilterEqual("a2User.id", userId);
		search.addSort("sort", false);
		List<A2UserDesktop> desktopList = a2UserDesktopDao.search(search);
		
		DTOAssembler ass = DTOAssembler.newAssembler(A2UserDesktopDto.class);
		ass.assembleDtos(desktopDtoList, desktopList, null, null);
		
		result.setResultList(desktopDtoList);
		return result.success();
	}
	

	@Override
	public Result addMenu2Desktop(long userId, A2UserDesktopDto desktopDto){
		Result result = new Result(); 
		A2User user = a2UserDao.fetch(userId);
		//判断菜单是否存在
		String text = desktopDto.getText();
		Search search = new Search();
		search.addFilterEqual("text", text);
		search.addFilterEqual("a2User.id", user.getId());
		int c = a2UserDesktopDao.count(search);
		if(c>0){
			return result.fault("菜单已存在");
		}
		
		
		A2UserDesktop desktop = new A2UserDesktop();
		DTOAssembler ass = DTOAssembler.newAssembler(A2UserDesktopDto.class);
		ass.assembleEntity(desktopDto, desktop, null, null);
		desktop.setA2User(user);
		a2UserDesktopDao.create(desktop);
		
		return result.success();
	}
	

	@Override
	public Result removeMenu2Desktop(long desktopId){
		Result result = new Result(); 
		
		a2UserDesktopDao.deleteById(desktopId);
		
		return result.success();
	}



	@Override
	public Result resetPassword(long userId, String passwordNew){
		Result result = new Result();
		A2User a2User = a2UserDao.fetch(userId);
		a2User.setPassword(passwordNew);
		a2User.setAppPassword(passwordNew);
		a2UserDao.update(a2User);
		return result.success();
	}

}

